package dse.messages.singleversion;

import dse.DataObject;
import dse.DataShare;
import dse.Experiment;
import dse.ExperimentRecorder;
import dse.Node;
import dse.Version;
import dse.messages.Message;
import dse.messages.MessageHandler;
import dse.messages.MessageSender;
import dse.messages.MessageType;
import dse.messages.multiversion.VersionReader;

public class RequestShareWithVersionMessageHandler extends MessageSender
		implements MessageHandler {
	private Version version;
	private DataObject dobj;
	private VersionReader reader;
	private boolean ir;
	
	public RequestShareWithVersionMessageHandler(Experiment experiment, DataObject dobj, Version version, VersionReader reader, boolean ir)
	{
		super(experiment);
		
		this.version = version;
		this.dobj = dobj;
		this.reader = reader;
		this.ir = ir;
	}
	
	@Override
	public boolean acceptMessage(Message message) {
		// TODO Auto-generated method stub
		return true;
	}

	@Override
	public void messageInterupted(ExperimentRecorder recorder, Message message,
			double time) {
		// TODO Auto-generated method stub
		if(ExperimentRecorder.debug)
			recorder.debug(this, "msgIntrpt: " + message, time);
		reader.readVersion(recorder, message.to(), null, time);
	}

	@Override
	public void messageReceived(ExperimentRecorder recorder, Message message,
			double time) {
		// TODO Auto-generated method stub
		if(ExperimentRecorder.debug)
			recorder.debug(this, "msgRcvd: " + message, time);
		if (message.messageType() != MessageType.RequestShareWithVersion) {
			recorder.warn(
					"RequestShareWithVersionMessageHandler recieved " + 
					message.messageType() + " message."
					);
			return;
		}	
		if(reader.getTransaction().id() == -1){
			System.out.println("id/" + message.id() + " type/" + message.messageType() + " from/" + message.from() + " to/" + message.to()
					+ " start/" + message.startTime() + " arrive/" + message.endTime() + " deliver/" + message.deliverTime());
		}
		// What do we know about the share?
		Node receiver = message.to();
		
		// Does the receiver have the share?
		DataShare share = receiver.getDataShare(dobj);
		
		if (share != null)
		{
			// Then we need to send a new message BACK (thats why to and from
			// are reversed!
			Version v = share.getShareWithVersion(version);
			if(ir){
				if(v != null)
					share.addCurReads(reader.getTransaction(), v);
				else if(!share.hasSent(reader.getTransaction(), share.getLatest()))
					v = share.getLatest();
			}
			else{
				if(v == null)
					v = share.getLatest();
			}
			Message m = super.createShareDownloadMessage(receiver, message.from(), dobj, v, 
					message.purpose(), reader);
			if(ExperimentRecorder.debug)
				recorder.debug(this, "new msg: " + m, time);
			experiment.messageQueue().enqueueMessage(m, time);
		}
		else
			this.messageInterupted(recorder, message, time);
	}
}
